/**************************************************************/
/*                                                            */
/*                     Класс QwtChartZoom                     */
/*                         Версия 1.1                         */
/*                                                            */
/* Обеспечивает интерфейс изменения масштаба и границ графика */
/* QwtPlot в стиле компонента TChart (Delphi, C++Builder).    */
/*                                                            */
/* Разработал Мельников Сергей Андреевич,                     */
/* г. Каменск-Уральский Свердловской обл., 2011 г.            */
/*                                                            */
/* Разрешается свободное использование и распространение.     */
/* Упоминание автора обязательно.                             */
/*                                                            */
/**************************************************************/

#ifndef QWTCHARTZOOM_H
#define QWTCHARTZOOM_H

#include <QObject>
#include <QEvent>
#include <QMouseEvent>
#include <qwt_plot.h>
#include <qwt_plot_canvas.h>

class QwtChartZoom : public QObject
{
    Q_OBJECT

public:
    // конструктор
    explicit QwtChartZoom(QwtPlot *,QObject * = 0);

    // установка цвета рамки, задающей новый размер графика
    void setRubberBandColor(QColor);
    // фиксация текущих границ графика в качестве исходных
    void fixBoundaries();
    // задание коэффициента масштабирования графика
    // при вращении колеса мыши
    void setWheelFactor(double);

protected:
    // обработчик всех событий
    bool eventFilter(QObject *,QEvent *);

private:
    double isb_xl,isb_xr;   // Исходные границы графика по оси x
    double isb_yb,isb_yt;   // исходные границы графика по оси y
    bool isbF;              // Флаг, задающий необходимость запомнить исходные границы графика
                            // Если isbF сброшен, то при первом нажатии на кнопку текущие границы
                            // графика будут сохранены в переменных isb_xl,isb_xr,isb_yb,isb_yt,
                            // и при отмене масштабирования и перемещения график будет возвращаться
                            // именно к этим границам
    // Значения типа текущего преобразования графика
    //     ctNone - нет преобразования
    //     ctZoom - изменение масштаба
    //     ctDrag - перемещение графика
    //     ctWheel - режим Wheel (изменение масштаба при вращении колеса мыши)
    // (значение, отличающееся от ctNone действует только пока
    // нажата левая или правая кнопка мыши или клавиша Ctrl)
    enum QConvType {ctNone,ctZoom,ctDrag,ctWheel};
    QConvType convType;     // Тип текущего преобразования графика
    double scb_xl,scb_xr;   // Текущие границы графика по оси x в момент начала преобразования
    double scb_yb,scb_yt;   // Текущие границы графика по оси y в момент начала преобразования
    int scp_x,scp_y;        // Положение курсора в момент начала преобразования
                            // (в пикселах относительно канвы QwtPlot)
    double cs_kx,cs_ky;     // Текущие масштабирующие множители по осям x и y
                            // (изменение координаты при перемещении на один пиксел)
    double sfact;           // Коэффициент, определяющий изменение масштаба графика
                            // при вращении колеса мыши (по умолчанию равен 1.2)
    QwtPlot *qwtp;          // Компонент QwtPlot, который отображает график
    QWidget *zwid;          // Виджет для отображения рамки, задающей новый размер графика
    QColor zwClr;           // Цвет рамки, задающей новый размер графика
    QCursor tCursor;        // Буфер для временного хранения курсора

    void storeCursor();     // сохранение текущего курсора
    void setCursor(QCursor);// установка курсора
    void restCursor();      // восстановление курсора

    // обработчик обычных событий от мыши
    void procMouseEvent(QEvent *);

    // обработчик нажатия на кнопку мыши
    void procMouseButtonPress(QMouseEvent *);
    // обработчик перемещения мыши
    void procMouseMove(QMouseEvent *);
    // обработчик отпускания кнопки мыши
    void procMouseButtonRelease(QMouseEvent *);

    // включение изменения масштаба
    void startZoom();
    // выделение новых границ графика для изменения масштаба
    void selectZoomRect(QMouseEvent *);
    // выполнение изменения масштаба
    void execZoom(QMouseEvent *);

    // включение перемещения графика
    void startDrag();
    // выполнение перемещения графика
    void execDrag(QMouseEvent *);
    // выключение перемещения графика
    void endDrag();

    // обработчик нажатия/отпускания клавиши Ctrl
    void switchWheel(QEvent *);
    // обработчик вращения колеса мыши
    void procWheel(QEvent *);

    // фактическая фиксация текущих границ графика
    // в качестве исходных (если флаг isbF сброшен)
    void fixBounds();
    // восстановление исходных границ графика
    void restBounds();
};

#endif // QWTCHARTZOOM_H
